#pragma once
#include "mutex.hpp"
#include "sem.hpp"
#include <vector>
#define default_size 5
using namespace sem_module;
using namespace mutex_module;
template <class T>
class ring_queue
{
public:
    ring_queue(unsigned int cap = default_size)
    :_ring_queue(cap),
     _pstep(0),
    _cstep(0),
    _blank_sem(cap),
    _data_sem(0),
    _cap(cap),
    _testnum(1){}
    void e_queue(T& in)
    {
        _blank_sem.P();
        {
        _pmutex.lock();
        _ring_queue[_pstep]=in;
        _pstep++;
        _pstep%=_cap;
        _pmutex.unlock();
        }
        _data_sem.V();
    }
    void pop(T& out)
    {
        _data_sem.P();
        {
            _cmutex.lock();
            out=_ring_queue[_cstep];
            //printf("期望的是%d,实际是%d\n",_testnum,out);
            _testnum++;
            _cstep++;
            _cstep%=_cap;
            _cmutex.unlock();
        }
        _blank_sem.V();
    }

    ~ring_queue(){}
private:
    std::vector<T> _ring_queue;
    unsigned int _cap;
    //表示消费者和生产者应该所处的两个位置
    int _pstep;
    int _cstep;
    //两个信号量分别表示消费者和生产者的
    sem _blank_sem;
    sem _data_sem;
    //消费者和生产者两把锁
    mutex _pmutex;
    mutex _cmutex;
    int _testnum;
};